/*
 *
 * Copyright (C) 2012 Walter Lütgenau
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 */
package offset.nodes.client.veditor.view.instance;

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.HashMap;
import java.util.Iterator;
import javax.swing.JFrame;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumnModel;
import offset.nodes.client.editor.Editor;
import offset.nodes.client.editor.model.messages.TemplateInstanceEditorResult;
import offset.nodes.client.model.Server;
import offset.nodes.client.view.SimpleDialog;
import offset.nodes.client.xpath.view.XPathPanel;
import offset.nodes.client.virtual.model.SimpleQuery;

/**
 *
 * @author Walter Lütgenau
 */
public class VirtualPageInstancePanel extends javax.swing.JPanel {

    protected static final int COLUMN_NAME = 0;
    protected static final int COLUMN_QUERY = 1;
    protected static final int COLUMN_NAME_WIDTH = 80;
    Editor editor;
    Server server;
    String nodeType;
    boolean initialized = false;

    /** Creates new form VirtualPageInstancePanel */
    public VirtualPageInstancePanel() {
        initComponents();
        initTables();
    }

    public void initTables() {
        TableColumnModel tcm = secondaryQueryTable.getColumnModel();
        tcm.getColumn(COLUMN_NAME).setPreferredWidth(COLUMN_NAME_WIDTH);
        tcm.getColumn(COLUMN_NAME).setMinWidth(COLUMN_NAME_WIDTH);
        tcm.getColumn(COLUMN_NAME).setMaxWidth(COLUMN_NAME_WIDTH);

        MouseListener secondaryQueryMouseListener = new MouseAdapter() {

            public void mousePressed(MouseEvent e) {
                if (e.getClickCount() == 2)
                    configureSecondaryQuery(null);
            }
        };
        
        secondaryQueryTable.addMouseListener(secondaryQueryMouseListener);

        tcm = selectQueryTable.getColumnModel();
        tcm.getColumn(COLUMN_NAME).setPreferredWidth(COLUMN_NAME_WIDTH);
        tcm.getColumn(COLUMN_NAME).setMinWidth(COLUMN_NAME_WIDTH);
        tcm.getColumn(COLUMN_NAME).setMaxWidth(COLUMN_NAME_WIDTH);

        MouseListener selectQueryMouseListener = new MouseAdapter() {

            public void mousePressed(MouseEvent e) {
                if (e.getClickCount() == 2)
                    configureSelectQuery(null);
            }
        };

        selectQueryTable.addMouseListener(selectQueryMouseListener);
    }

    public boolean isInitialized() {
        return initialized;
    }

    /**
     * Return the secondary queries as configured by the user
     *
     * @return
     */
    public String[] getSecondaryQueries() {
        DefaultTableModel table = (DefaultTableModel) secondaryQueryTable.getModel();

        String[] queries = new String[table.getRowCount()];
        for (int i = 0; i < table.getRowCount(); i++) {
            String key = (String) table.getValueAt(i, COLUMN_NAME);
            String value = (String) table.getValueAt(i, COLUMN_QUERY);

            queries[i] = key + "=" + value;
        }

        return queries;
    }

    /**
     * Return the select queries as configured by the user
     *
     * @return
     */
    public String[] getSelectQueries() {
        DefaultTableModel table = (DefaultTableModel) selectQueryTable.getModel();

        String[] queries = new String[table.getRowCount()];
        for (int i = 0; i < table.getRowCount(); i++) {
            String key = (String) table.getValueAt(i, COLUMN_NAME);
            String value = (String) table.getValueAt(i, COLUMN_QUERY);

            queries[i] = key + "=" + value;
        }

        return queries;
    }

    /**
     * Update the queries according to the actual editor settings
     * @param queries
     */
    public void updateSecondaryQueries(HashMap<String, String> queries) {
        int row = 0;
        DefaultTableModel table = (DefaultTableModel) secondaryQueryTable.getModel();

        if (queries != null && queries.size() > 0) {
            Iterator<String> q = queries.keySet().iterator();
            for (row = 0; row < queries.size() && q.hasNext(); row++) {
                String name = q.next();

                String value = queries.get(name);

                while (table.getRowCount() <= row) {
                    table.addRow((Object[]) null);
                }
                table.setValueAt(name, row, COLUMN_NAME);
                table.setValueAt(value, row, COLUMN_QUERY);
            }

            int rows = table.getRowCount();
            for (int i = row; i < rows; i++) {
                table.removeRow(row);
            }

            if (table.getRowCount() > 0) {
                secondaryQueryTable.getSelectionModel().setAnchorSelectionIndex(0);
                secondaryQueryTable.getSelectionModel().setLeadSelectionIndex(0);
            }
        }
    }

    /**
     * Update the queries according to the actual editor settings
     * @param queries
     */
    public void updateSelectQueries(HashMap<String, String> queries) {
        int row = 0;
        DefaultTableModel table = (DefaultTableModel) selectQueryTable.getModel();

        if (queries != null && queries.size() != table.getRowCount()) {
            Iterator<String> q = queries.keySet().iterator();
            for (row = 0; row < queries.size() && q.hasNext(); row++) {
                String name = q.next();

                String value = queries.get(name);

                while (table.getRowCount() <= row) {
                    table.addRow((Object[]) null);
                }
                table.setValueAt(name, row, COLUMN_NAME);
                table.setValueAt(value, row, COLUMN_QUERY);
            }

            int rows = table.getRowCount();
            for (int i = row; i < rows; i++) {
                table.removeRow(row);
            }

            if (table.getRowCount() > 0) {
                selectQueryTable.getSelectionModel().setAnchorSelectionIndex(0);
                selectQueryTable.getSelectionModel().setLeadSelectionIndex(0);
            }
        }
    }

    /**
     * Set the node type
     * @param nodeType
     */
    public void init(Editor editor, Server server, String nodeType) {
        this.editor = editor;
        this.server = server;
        this.nodeType = nodeType;

        updateSecondaryQueries((HashMap<String, String>) editor.getProperties().get(Editor.PROP_SECONDARY_QUERIES));
        updateSelectQueries((HashMap<String, String>) editor.getProperties().get(Editor.PROP_SELECT_QUERIES));

        initialized = true;
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        secondaryQueryTable = new javax.swing.JTable();
        queryLabel1 = new javax.swing.JLabel();
        queryButton3 = new javax.swing.JButton();
        selectQueryLabel = new javax.swing.JLabel();
        selectQueryButton = new javax.swing.JButton();
        jScrollPane2 = new javax.swing.JScrollPane();
        selectQueryTable = new javax.swing.JTable();

        secondaryQueryTable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {
                "Name", "Query"
            }
        ) {
            Class[] types = new Class [] {
                java.lang.String.class, java.lang.String.class
            };
            boolean[] canEdit = new boolean [] {
                false, false
            };

            public Class getColumnClass(int columnIndex) {
                return types [columnIndex];
            }

            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return canEdit [columnIndex];
            }
        });
        secondaryQueryTable.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        jScrollPane1.setViewportView(secondaryQueryTable);

        java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("offset/nodes/client/editor/view/resources/EditorBundle"); // NOI18N
        queryLabel1.setText(bundle.getString("virtualPageInstance.secondaryQueries")); // NOI18N

        queryButton3.setText(bundle.getString("virtualPageInstance.edit")); // NOI18N
        queryButton3.setPreferredSize(new java.awt.Dimension(67, 23));
        queryButton3.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                configureSecondaryQuery(evt);
            }
        });

        selectQueryLabel.setText(bundle.getString("virtualPageInstance.selectQueries")); // NOI18N

        selectQueryButton.setText(bundle.getString("virtualPageInstance.edit")); // NOI18N
        selectQueryButton.setPreferredSize(new java.awt.Dimension(67, 23));
        selectQueryButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                configureSelectQuery(evt);
            }
        });

        selectQueryTable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {
                "Name", "Query"
            }
        ) {
            Class[] types = new Class [] {
                java.lang.String.class, java.lang.String.class
            };
            boolean[] canEdit = new boolean [] {
                false, false
            };

            public Class getColumnClass(int columnIndex) {
                return types [columnIndex];
            }

            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return canEdit [columnIndex];
            }
        });
        selectQueryTable.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        jScrollPane2.setViewportView(selectQueryTable);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(selectQueryLabel)
                        .addGap(22, 22, 22)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addComponent(selectQueryButton, javax.swing.GroupLayout.PREFERRED_SIZE, 75, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 439, Short.MAX_VALUE)))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addComponent(queryLabel1)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addGroup(layout.createSequentialGroup()
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 364, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addComponent(queryButton3, javax.swing.GroupLayout.PREFERRED_SIZE, 75, javax.swing.GroupLayout.PREFERRED_SIZE))
                            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 439, Short.MAX_VALUE))))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(44, 44, 44)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 71, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(selectQueryButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addComponent(selectQueryLabel))
                .addGap(59, 59, 59)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 71, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(queryButton3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addComponent(queryLabel1))
                .addGap(20, 20, 20))
        );
    }// </editor-fold>//GEN-END:initComponents

    private void configureSecondaryQuery(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_configureSecondaryQuery
        int selected = secondaryQueryTable.getSelectedRow();
        if (selected < 0)
            return;

        String queryString = (String) secondaryQueryTable.getModel().getValueAt(selected, COLUMN_QUERY);
        SimpleQuery query = new SimpleQuery();
        query.setQueryParametersFromString(queryString);
        QueryPanel queryPanel = new QueryPanel(server, nodeType, query, true);

        SimpleDialog dialog = new SimpleDialog(new JFrame(), true, queryPanel);
        dialog.setVisible(true);
        
        if (dialog.getReturnStatus() == SimpleDialog.OK)
            secondaryQueryTable.getModel().setValueAt(queryPanel.getQueryParameters().getQueryStringFromQueryParameters(),
                    selected, COLUMN_QUERY);
    }//GEN-LAST:event_configureSecondaryQuery

    private void configureSelectQuery(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_configureSelectQuery
        int selected = selectQueryTable.getSelectedRow();
        if (selected < 0)
            return;

        String queryString = (String) selectQueryTable.getModel().getValueAt(selected, COLUMN_QUERY);
        XPathPanel xpathPanel = new XPathPanel(server);
        xpathPanel.setMode(XPathPanel.MODE_SELECT_QUERY);
        if (queryString != null && queryString.length() > 0)
            xpathPanel.setXPathQuery(null, queryString);
        
        SimpleDialog dialog = new SimpleDialog(null, true, xpathPanel);
        dialog.setSize(555, 720);
        dialog.setVisible(true);

        if (dialog.getReturnStatus() == SimpleDialog.OK)
            selectQueryTable.getModel().setValueAt(xpathPanel.getXPathQuery(), selected, COLUMN_QUERY);

    }//GEN-LAST:event_configureSelectQuery
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JButton queryButton3;
    private javax.swing.JLabel queryLabel1;
    private javax.swing.JTable secondaryQueryTable;
    private javax.swing.JButton selectQueryButton;
    private javax.swing.JLabel selectQueryLabel;
    private javax.swing.JTable selectQueryTable;
    // End of variables declaration//GEN-END:variables
}
